

let {Vector3} = require('../math');

const tmpv1 = new Vector3();
const tmpv2 = new Vector3();
const tmpv3 = new Vector3();

const v0 = new Vector3();
const v1 = new Vector3();
const v2 = new Vector3();


/**
 *
 * @param  data:{
    positions: number[],
    normals: number[],
    texCoords: number[],
    indices: number[]
}
 */
function computeNormals(data) {

    let indices = data.indices;
    let positions = data.positions;
    data.normals.length = data.positions.length;

    let v01 = tmpv1;
    let v12 = tmpv2;
    let nor = tmpv3;

    // 先计算所有的面法线
    let faceLen = indices.length / 3;
    let f = {};
    let v = {};  // 顶点索引i属于 哪几个面
    for (let i = 0; i < faceLen; ++i) {
        let i0 = indices[3 * i];
        let i1 = indices[3 * i + 1];
        let i2 = indices[3 * i + 2];

        if (!v[i0]){
            v[i0] = [];
        }
        v[i0].push(i);

        if (!v[i1]){
            v[i1] = [];
        }
        v[i1].push(i);

        if (!v[i2]){
            v[i2] = [];
        }
        v[i2].push(i);


        v0.set( positions[3 * i0], positions[3 * i0 + 1], positions[3 * i0 + 2]);
        v1.set( positions[3 * i1], positions[3 * i1 + 1], positions[3 * i1 + 2]);
        v2.set( positions[3 * i2], positions[3 * i2 + 1], positions[3 * i2 + 2]);

        v01.subVectors(v1,v0);
        v12.subVectors(v2,v1);
        nor.crossVectors(v01,v12);
        nor.normalize();
        f[i] = new Vector3(nor.x,nor.y,nor.z);
    }

    // 计算顶点的平均法线
    let posLen = positions.length / 3;
    let sum = tmpv1;
    for (let i = 0; i < posLen; ++i){
        sum.set(0,0,0);
        v[i].forEach(faceIdx=>{
            sum.add(f[faceIdx]);
        });
        sum.normalize();
        data.normals[3 * i] = sum.x;
        data.normals[3 * i + 1] = sum.y;
        data.normals[3 * i + 2] = sum.z;
    }
}

module.exports = computeNormals;
